/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.yonsei.iwb.sdt.refinement;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.NodeIterator;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import edu.yonsei.iwb.sdt.datastructure.TargetInstance;
import java.util.List;
import java.util.Vector;
import edu.yonsei.iwb.sdt.ontology.PropertyArc;

/**
 *
 * @author JDK
 */
public class CardinalityRestrictionRefinement extends Refinement {

    private String name = new String();
    private ExpandingHistory eh;
    private String corename = new String();
    private int standard;
    private PropertyArc conditionp;

//    private Property property;
    public CardinalityRestrictionRefinement(String name, String corename, ExpandingHistory eh) {
        this.name = name;
        this.eh = eh;
        this.corename = corename;
        super.refinementType = RefinementType.CARDINALITYRESTRICTION;
    }

    public CardinalityRestrictionRefinement(CardinalityRestrictionRefinement crr) {
        this.name = crr.getName();
        this.eh = crr.getExpandingHistory();
        this.corename = crr.getCoreName();
        this.standard = crr.getStandard();
        this.conditionp = crr.getConditionp();
        super.refinementType = RefinementType.CARDINALITYRESTRICTION;
    }

    public CardinalityRestrictionRefinement(int standard, String prefix, PropertyArc pa) {

        if (pa.getDirection()) {
            this.name = prefix + standard + " " + pa.getProperty();
            this.corename = prefix + standard + " " + pa.getProperty();
        } else {
            this.name = prefix + standard + " " + pa.getProperty();
            this.corename = prefix + standard + " " + pa.getProperty() + "￣";
        }

        this.cc = new ConstraintConstructor(prefix, standard, pa.getProperty());
        this.standard = standard;
        this.conditionp = pa;
        super.refinementType = RefinementType.CARDINALITYRESTRICTION;
    }

    public CardinalityRestrictionRefinement(int standard, String prefix, PropertyArc corepa, ExpandingHistory eh) {
        this.eh = eh;
        Vector<String> quantifiers = this.eh.getQuantifierSet();
        Vector<PropertyArc> propertySet = this.eh.getPropertySet();
        if (corepa.getDirection()) {
            this.name = prefix + standard + " " + corepa.getProperty();
        } else {
            this.name = prefix + standard + " " + corepa.getProperty() + "￣";
        }

        for (int i = 0; i < propertySet.size(); i++) {
            PropertyArc pa = propertySet.get(i);
            String p = pa.getProperty();
            String q = quantifiers.get(i);

            if (pa.getDirection()) {
                this.name = q + " " + p + ".(" + this.name + ")";
            } else {
                this.name = q + " " + p + "￣.(" + this.name + ")";
            }
        }

        this.standard = standard;
        this.conditionp = corepa;

//        this.corename = prefix + standard +" " + corepa.getLocalName().toString();
//        this.cc = new ConstraintConstructor(prefix, standard, corepa.getProperty());
        super.refinementType = RefinementType.CARDINALITYRESTRICTION;

    }

    @Override
    public ExpandingHistory getExpandingHistory() {
        return this.eh;
    }

//    public Property getPropertyOfRefinement(){
//        return this.property;
//    }
    @Override
    public void generateRefinementName() {
        super.refinement_name = this.name;
    }

    @Override
    public Refinement generateUpdatedRefinement(Vector<TargetInstance> instanceSet) {
        Refinement ref = new CardinalityRestrictionRefinement(this);
//        Refinement ref = new CardinalityRestrictionRefinement(this.name, this.corename, this.eh);
        ref.setBranchingType(this.branching_type);
        ref.setConstraintConstructor(this.cc);

        Vector<TargetInstance> oldinsSet = this.getInstanceSet();        
        for (int i = 0; i < instanceSet.size(); i++) {
            TargetInstance ti = instanceSet.get(i);                        
            if (oldinsSet.contains(ti)) {                
                ref.setInstanceSet(ti);                
            }
        }


//        private boolean refinement_type = true;
//        protected String refinement_name;
//        private Vector<Resource> instanceSet;
        return ref;
    }

    public String getName() {
        return name;
    }

    public int getStandard() {
        return standard;
    }

    public PropertyArc getConditionp() {
        return conditionp;
    }

    @Override
    public String getCoreName() {
        return this.corename;
    }

    @Override
    public Vector<Resource> getConstraintMatcherInstance(Model model) {
        
//        StmtIterator iter = model.listStatements(null, this.conditionp.getProperty(), (RDFNode) null);
//        Vector<Resource> css = new Vector<Resource>();
        Vector<Resource> result = new Vector<Resource>();
//
//        if (this.conditionp.getDirection()) {
//            while (iter.hasNext()) {
//                Statement st = iter.nextStatement();                
//                if (!css.contains(st.getSubject())) {
//                    css.add(st.getSubject());
//                }                
//            }
//            
//            for (int i = 0; i < css.size(); i++) {
//                Resource value = css.get(i);
//                List list;                
//                NodeIterator ni = model.listObjectsOfProperty(value, this.conditionp.getProperty());
//                list = ni.toList();                
//                if (list.size() > standard) {
//                    result.add(value);
//                }
//            }
//            
//        } else {
//            while (iter.hasNext()) {
//                Statement st = iter.nextStatement();                
//                if (!css.contains(st.getObject().asResource())) {
//                    css.add(st.getObject().asResource());
//                }                
//            }
//            
//            for (int i = 0; i < css.size(); i++) {
//                Resource value = css.get(i);
//                List list;             
//                ResIterator res = model.listResourcesWithProperty(this.conditionp.getProperty(), value);
//                list = res.toList();
//                if (list.size() > standard) {
//                    result.add(value);
//                }
//            }
//        }

        return result;
    }
}
